package edu.sysu.cshare.control;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.hibernate.Session;

import edu.sysu.cshare.model.Course;
import edu.sysu.cshare.model.Group;
import edu.sysu.cshare.model.Homework;
import edu.sysu.cshare.model.SubmitInfo;
import edu.sysu.cshare.model.User;
import edu.sysu.cshare.util.ContinueFTP;
import edu.sysu.cshare.util.HibernateSessionFactory;

public class HomeworkManager {
	public static boolean isStuInCourse(User user, Course course) {
		Session ss = HibernateSessionFactory.getSession();
		List<User> stus = ss.createQuery("select c.students from Course c")
				.list();
		return stus.contains(user);
	}

	public static Homework getHomeworkById(long id) {
		Session ss = HibernateSessionFactory.getSession();
		ss.beginTransaction();
		return (Homework) ss.load(Homework.class, id);
	}

	public static SubmitInfo getSubmitInfoById(long id) {
		return (SubmitInfo) HibernateSessionFactory.getSession().load(
				SubmitInfo.class, id);
	}

	private User actor;

	public User getActor() {
		return actor;
	}

	public HomeworkManager(User actor) {
		this.actor = actor;
	}

	/**
	 * 添加一项新的作业信息到系统
	 * 
	 * @param homework
	 * @throws Exception
	 */
	public void addItem(Homework homework) throws Exception {

		if (actor.canManageHomework()) {
			Session ss = HibernateSessionFactory.getSession();
			ss.beginTransaction();

			for (User stu : homework.getCourse().getStudents()) {
				SubmitInfo subinfo = new SubmitInfo(homework, stu);
				if (homework.getSubmitByGroup()) {
					subinfo.setGroup(stu.getGroupByCourse(homework.getCourse()));
				}
				ss.save(subinfo);
			}
			if (homework.getDirPath() != null) {
				ContinueFTP ftp = new ContinueFTP();
				ftp.connect();
				ftp.makeDir(homework.getDirPath());
			}
			ss.save(homework);
			ss.getTransaction().commit();
		} else {
			throw new Exception("你不能添加作业信息,想提升权限吗? 请联系管理员");
		}
	}

	/**
	 * 管理员打包下载已经提交的作业项目
	 * 
	 * @param homework
	 *            打包下载的作业项目
	 * @param localDir
	 *            本地存放路径 形如"D:\\temp\\download\\"
	 * @throws Exception
	 */
	public void batchDownload(Homework homework, String localDir)
			throws Exception {

		if (actor.canManageHomework()) {
			if (new File(localDir).isDirectory()) {
				if (!localDir.endsWith("\\")) {
					localDir = localDir + "\\";
				}
				if (!new File(localDir + homework.getDirPath()).exists()) {
					new File(localDir + homework.getDirPath()).mkdir();
				}
			} else {
				throw new Exception("指定目录无效");
			}
			ContinueFTP ftp = new ContinueFTP();
			ftp.connect();

			if (homework.getSubmitByGroup()) {
				for (Group g : homework.getCourse().getGroups()) {
					SubmitInfo sinfo = g.getSubinfoByHomework(homework);
					if (sinfo.getSubmitDate() != null) {
						String filePath = sinfo.getSavePath();
						ftp.download(filePath, localDir + filePath);
					}
				}
			} else {
				for (User u : homework.getCourse().getStudents()) {
					SubmitInfo sinfo = u.getSubmitInfoByHomework(homework);
					if (sinfo.getSubmitDate() != null) {
						String filePath = sinfo.getSavePath();
						ftp.download(filePath, localDir + filePath);
					}
				}
			}
		} else {
			throw new Exception("你不能进行批量下载操作");
		}

	}

	/**
	 * 删除一项作业
	 * 
	 * @param homework
	 * @throws Exception
	 */
	public void deleteItem(Homework homework) throws Exception {
		if (actor.canManageHomework()) {
			Session ss = HibernateSessionFactory.getSession();
			ss.beginTransaction();
			// NOTE also delete associate subinfo?
			ss.delete(homework);
			ss.getTransaction().commit();
		} else {
			throw new Exception("你无权进行此操作 作业不是想不做就不做的");
		}

	}

	/**
	 * 用户重新下载自己提交过的作业
	 * 
	 * @param homework
	 * @param localDir
	 *            本地保存目录 形如"D:\\temp"
	 * @throws Exception
	 */
	public void downloadMine(Homework homework, String localDir)
			throws Exception {
		if (actor.canSubmit()) {
			ContinueFTP ftp = new ContinueFTP();
			try {
				String filePath = actor.getSubmitInfoByHomework(homework)
						.getSavePath();
				String filename = filePath
						.substring(filePath.lastIndexOf("\\"));
				ftp.connect();
				ftp.download(actor.getSubmitInfoByHomework(homework)
						.getSavePath(), localDir + filename);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			throw new Exception("算了吧");
		}

	}

	/**
	 * 学生查看属于自己的所有作业
	 * 
	 * @return 提交信息列表
	 * @throws Exception
	 */
	public List<SubmitInfo> getAll() throws Exception {

		if (actor.canSubmit()) {
			return actor.getSubmitInfos();
			/*
			 * Session ss = HibernateSessionFactory.getSession();
			 * ss.beginTransaction(); return
			 * ss.createQuery("from SubmitInfo si where si.user =:user ")
			 * .setEntity("user", actor).list();
			 */
		} else {
			throw new Exception("你就不用了吧");
		}

	}

	/**
	 * 老师查看自己布置的作业
	 * 
	 * @return 作业列表
	 * @throws Exception
	 */
	public List<Homework> getAssignments() throws Exception {
		if (actor.canManageHomework()) {
			Session ss = HibernateSessionFactory.getSession();
			return ss
					.createQuery(
							"from Homework hm where hm.course.teacher =:teacher")
					.setEntity("teacher", actor).list();

		} else {
			throw new Exception("你又不是老师");
		}

	}

	/**
	 * 通过判断提交日期是否为空 返回未提交作业的信息列表
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<SubmitInfo> getUnsubmit() throws Exception {
		if (actor.canSubmit()) {
			// NOTE WHY NO HQL HERE?
			List<SubmitInfo> result = new ArrayList<SubmitInfo>();
			for (SubmitInfo sinfo : actor.getSubmitInfos()) {
				if (sinfo.getSubmitDate() == null) {
					result.add(sinfo);
				}
			}
			return result;
		} else {
			throw new Exception("你真的需要交作业吗?");
		}

	}

	public List<SubmitInfo> getUnsubmit2() throws Exception {
		if (actor.canSubmit()) {
			// NOTE WHY NO HQL HERE?
			List<SubmitInfo> result = new ArrayList<SubmitInfo>();
			Session ss = HibernateSessionFactory.getSession();
			result = ss
					.createQuery(
							"from SubmitInfo si where si.user= ? and si.submitDate = null")
					.setEntity(0, actor).list();
			return result;
		} else {
			throw new Exception("你真的需要交作业吗?");
		}

	}

	public List<SubmitInfo> getSubmitted() throws Exception {
		if (actor.canSubmit()) {
			// NOTE WHY NO HQL HERE? found out using hql will produce 1 more sql
			// query
			List<SubmitInfo> result = new ArrayList<SubmitInfo>();
			for (SubmitInfo sinfo : actor.getSubmitInfos()) {
				if (sinfo.getSubmitDate() != null) {
					result.add(sinfo);
				}
			}
			return result;
		} else {
			throw new Exception("你真的需要交作业吗?");
		}

	}

	public void merge(Homework homework) {
		Session ss = HibernateSessionFactory.getSession();
		ss.beginTransaction();
		// ss.saveOrUpdate(homework);
		ss.merge(homework);
		ss.getTransaction().commit();
	}

	/**
	 * 提交作业 需要上传的作业项目:上传文件,设置提交日期 ,通过"上传"button调用
	 * 不需要上传的作业项目:filePath为null,只设置提交日期,通过"我做完了"button调用
	 * 
	 * @param homework
	 *            要提交的作业项目
	 * @param filePath
	 *            作业文件的绝对路径 如果是null则只设置做完日期
	 * @throws Exception
	 */

	public void submit(Homework homework, String filePath) throws Exception {
		if (actor.canSubmit()) {
			// TODO 过期处理逻辑 现在是直接覆盖
			SubmitInfo sinfo = actor.getSubmitInfoByHomework(homework);

			// 如果不需要上传就记录一下 搞定
			if (!homework.shouldUpload()) {
				Session ss = HibernateSessionFactory.getSession();
				ss.beginTransaction();
				sinfo.setSubmitDate(Calendar.getInstance());
				ss.merge(sinfo);
				ss.getTransaction().commit();
				return;

				// 需要上传
			} else if (filePath != null) {

				// 格式判定
				if (!homework.getExtRestrict().equals("")&&
						homework
						.getExtRestrict()
						.toLowerCase()
						.indexOf(
								filePath.toLowerCase().substring(
										filePath.lastIndexOf(".") + 1)) == -1) {
					throw new Exception("文件格式不符合要求");
				}

				// 大小判定
				File temp = new File(filePath);
				if (homework.getMaxSize() != 0) {
					if (temp.length() / 1024 > homework.getMaxSize())
						throw new Exception("文件大小超过限制");

				}

				// 实际为"\filename.ext"
				String filename = filePath
						.substring(filePath.lastIndexOf("\\"));

				sinfo.setSavePath(homework.getDirPath() + filename);
				sinfo.setSubmitDate(Calendar.getInstance());
				ContinueFTP ftp = new ContinueFTP();
				ftp.connect();
				ftp.upload(filePath, homework.getDirPath() + filename);

				System.out.println("[" + homework.getDirPath() + filename
						+ "] UPLOADED");

				// 如果作业是按分组提交的,则小组所有人的相应subinfo 的提交时间都从null设置为当前时间
				if (homework.getSubmitByGroup()) {
					for (User stu : actor
							.getGroupByCourse(homework.getCourse())
							.getMembers()) {
						if (!stu.getId().equals(actor.getId())) {
							stu.getSubmitInfoByHomework(homework)
									.setSubmitDate(Calendar.getInstance());
							stu.getSubmitInfoByHomework(homework).setSavePath(
									homework.getDirPath() + filename);
						}
					}
				}
				System.out.println("mark1");
				Session ss = HibernateSessionFactory.getSession();
				ss.beginTransaction();
				ss.merge(sinfo);
				ss.getTransaction().commit();
			}
		}

		else {
			throw new Exception("你真的需要交作业吗?");
		}

	}
}
